////////////////////////////////////////////////////////////////////////////////
// This file is part of the Mist compiler.                                    //
//                                                                            //
// Copyright (C) 2008, 2009 The Mist project                                  //
//                                                                            //
// For a list of contributors, see the COMMITTERS file.                       //
//                                                                            //
// The Mist compiler is free software: you can redistribute it and/or modify  //
// it under the terms of the GNU General Public License as published by       //
// the Free Software Foundation, either version 3 of the License, or          //
// (at your option) any later version.                                        //
//                                                                            //
// The Mist compiler is distributed in the hope that it will be useful,       //
// but WITHOUT ANY WARRANTY; without even the implied warranty of             //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              //
// GNU General Public License for more details.                               //
//                                                                            //
// You should have received a copy of the GNU General Public License          //
// in the COPYING file. If not, see <http://www.gnu.org/licenses/>.           //
////////////////////////////////////////////////////////////////////////////////

///
/// \file
/// The file that contains the main function. It should handle command-line
/// arguments and initiate all phases of compilation.
///

////////////////////////////////////////////////////////////////////////////////
// Includes                                                                   //
////////////////////////////////////////////////////////////////////////////////

#include <iostream>
using std::cin;
using std::cout;

#include <fstream>
using std::ifstream;

#include "common/ptr.hpp"
#include "copyast.hpp"
#include "echo.hpp"
#include "finderror1.hpp"
#include "findproof.hpp"
#include "messages.hpp"
#include "parse.hpp"
#include "symbol.hpp"
#include "testvisit.hpp"
#include "tree.hpp"

////////////////////////////////////////////////////////////////////////////////
// Main Function                                                              //
////////////////////////////////////////////////////////////////////////////////

int main() {
	sptr<Messages> messages(new Messages);
	
	ifstream baseDeclarations("base.m");
	
	sptr<Symbol> symbolRoot = Symbol::construct_root();
	
	sptr<Declarations> astRoot = merged_declarations(
		parse<Declarations>(baseDeclarations, symbolRoot, vector<sptr<Expression> >(), messages, "base.m" ),
		parse<Declarations>(cin             , symbolRoot, vector<sptr<Expression> >(), messages, "(stdin)")
	);
	
	find_error_1(astRoot, messages);
	
	test_visit(astRoot);
	
	if (messages->count(Error) == 0) {
		find_proof(astRoot);
		cout << echo(astRoot, echo::PartialCorrectnessOutline | echo::TotalCorrectnessOutline);
	}
	
	if (messages->count() > 0) {
		if (messages->count(Warning) > 0)
			cout << "--------------------\n";
		cout << *messages;
	}
}
